package edu.se.jai.lesson05nacos.service;

import edu.se.jai.lesson05nacos.config.AppConfig;
import edu.se.jai.lesson05nacos.config.DatabaseConfig;
import edu.se.jai.lesson05nacos.config.RedisConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 业务配置服务
 * 负责监听配置变更并执行业务逻辑
 * 模拟实际业务场景中的配置变更处理
 */
@Service
@Slf4j
public class BusinessConfigService {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private DatabaseConfig databaseConfig;

    @Autowired
    private RedisConfig redisConfig;

    // 模拟业务统计
    private final AtomicInteger configChangeCount = new AtomicInteger(0);

    private LocalDateTime lastConfigChangeTime;

    /**
     * 监听配置环境变更事件
     * 当配置发生变更时，执行业务逻辑处理
     */
    @EventListener
    public void handleEnvironmentChange(EnvironmentChangeEvent event) {
        log.info("🔄 ===== 业务配置服务：配置变更事件触发 =====");
        log.info("📝 变更的配置键: {}", event.getKeys());
        log.info("⏰ 变更时间: {}", LocalDateTime.now());
        
        // 更新统计信息
        configChangeCount.incrementAndGet();

        lastConfigChangeTime = LocalDateTime.now();
        
        // 执行业务逻辑处理
        handleConfigChange(event.getKeys());
        
        // 打印当前配置状态
        printCurrentConfigStatus();
    }

    /**
     * 处理配置变更的业务逻辑
     */
    private void handleConfigChange(java.util.Set<String> changedKeys) {
        log.info("🔧 ===== 执行业务配置变更处理 =====");
        
        for (String key : changedKeys) {
            switch (key) {
                case "app.business.max-users":
                    handleMaxUsersChange();
                    break;
                case "app.business.enable-registration":
                    handleRegistrationToggle();
                    break;
                case "app.feature.enable-log":
                    handleLoggingToggle();
                    break;
                case "database.url":
                case "database.max-connections":
                    handleDatabaseConfigChange();
                    break;
                case "redis.host":
                case "redis.port":
                    handleRedisConfigChange();
                    break;
                default:
                    log.info("📋 配置项 {} 发生变更，执行通用处理逻辑", key);
                    break;
            }
        }
        
        log.info("✅ 业务配置变更处理完成");
    }

    /**
     * 处理最大用户数变更
     */
    private void handleMaxUsersChange() {
        Integer maxUsers = appConfig.getBusiness().getMaxUsers();
        log.info("👥 最大用户数已更新为: {}", maxUsers);
        
        // 模拟业务逻辑：重新计算用户配额
        if (maxUsers != null && maxUsers > 0) {
            log.info("📊 重新计算用户配额，当前最大用户数: {}", maxUsers);
            // 这里可以添加实际的业务逻辑，比如：
            // - 重新计算用户配额
            // - 更新缓存中的用户限制
            // - 通知其他服务更新用户限制
        }
    }

    /**
     * 处理用户注册开关变更
     */
    private void handleRegistrationToggle() {
        Boolean enableRegistration = appConfig.getBusiness().getEnableRegistration();
        log.info("✅ 用户注册功能状态: {}", enableRegistration ? "已启用" : "已禁用");
        
        // 模拟业务逻辑：更新注册服务状态
        if (Boolean.TRUE.equals(enableRegistration)) {
            log.info("🚀 启用用户注册服务，准备接收新用户注册");
        } else {
            log.info("⏸️ 禁用用户注册服务，停止接收新用户注册");
        }
    }

    /**
     * 处理日志功能开关变更
     */
    private void handleLoggingToggle() {
        Boolean enableLog = appConfig.getFeature().getEnableLog();
        log.info("📊 日志功能状态: {}", enableLog ? "已启用" : "已禁用");
        
        // 模拟业务逻辑：调整日志级别
        if (Boolean.TRUE.equals(enableLog)) {
            log.info("📝 启用详细日志记录，提高系统可观测性");
        } else {
            log.info("🔇 禁用详细日志记录，减少系统开销");
        }
    }

    /**
     * 处理数据库配置变更
     */
    private void handleDatabaseConfigChange() {
        log.info("🗄️ 数据库配置已更新");
        log.info("  🔗 数据库URL: {}", databaseConfig.getUrl());
        log.info("  🔢 最大连接数: {}", databaseConfig.getMaxConnections());
        
        // 模拟业务逻辑：重新初始化数据库连接池
        log.info("🔄 重新初始化数据库连接池...");
        // 这里可以添加实际的业务逻辑，比如：
        // - 重新创建数据库连接池
        // - 验证新的数据库连接
        // - 更新数据访问层的配置
    }

    /**
     * 处理Redis配置变更
     */
    private void handleRedisConfigChange() {
        log.info("🔴 Redis配置已更新");
        log.info("  🏠 Redis主机: {}", redisConfig.getHost());
        log.info("  🚪 Redis端口: {}", redisConfig.getPort());
        
        // 模拟业务逻辑：重新连接Redis
        log.info("🔄 重新连接Redis服务器...");
        // 这里可以添加实际的业务逻辑，比如：
        // - 重新创建Redis连接
        // - 验证新的Redis连接
        // - 更新缓存层的配置
    }

    /**
     * 打印当前配置状态
     */
    private void printCurrentConfigStatus() {
        log.info("📋 ===== 当前业务配置状态 =====");
        
        try {
            // 应用配置信息
            log.info("🔧 应用配置信息:");
            log.info("  📝 欢迎消息: {}", appConfig.getBusiness().getWelcomeMessage());
            log.info("  👥 最大用户数: {}", appConfig.getBusiness().getMaxUsers());
            log.info("  ✅ 启用注册: {}", appConfig.getBusiness().getEnableRegistration());
            log.info("  🌐 默认语言: {}", appConfig.getBusiness().getDefaultLanguage());
            log.info("  📊 启用日志: {}", appConfig.getFeature().getEnableLog());

            // 数据库配置信息
            log.info("🗄️ 数据库配置信息:");
            log.info("  🔗 数据库URL: {}", databaseConfig.getUrl());
            log.info("  🔢 最大连接数: {}", databaseConfig.getMaxConnections());

            // Redis配置信息
            log.info("🔴 Redis配置信息:");
            log.info("  🏠 Redis主机: {}", redisConfig.getHost());
            log.info("  🚪 Redis端口: {}", redisConfig.getPort());
            
            // 业务统计信息
            log.info("📊 业务统计信息:");
            log.info("  🔄 配置变更次数: {}", configChangeCount.get());
            log.info("  ⏰ 最后变更时间: {}", lastConfigChangeTime);
            
            log.info("📋 ===== 配置状态打印完成 =====");
        } catch (Exception e) {
            log.error("❌ 获取配置信息失败", e);
        }
    }

}
